// nice intro:
//   http://www.phpcompiler.org/articles/virtualinheritance.html

#include <cstddef>

typedef unsigned long size_t;

struct env
{
  int i;
  env(int);
  env(void) = delete;
};

struct Pad
{
  ptrdiff_t offs;
  ptrdiff_t tip;
  void* info;
};

struct c1 : virtual env
{
  c1(void) : env(42) {}
};
struct c2 : virtual env
{
  c2(void) : env(25) {}
  int get(void) { return i; }
  void redirect(env&, Pad&);
};

struct cas1 : c1, c2
{
  cas1(void) : env(11)
  {}
};

struct c1grr : env
{};



template <size_t T, size_t U>
struct Eq;

template <size_t T>
struct Eq<T, T> {};


template <typename T, typename U>
struct sameSize : Eq<sizeof(T), sizeof(U)>
{};

typedef sameSize<c1grr, c1> check1;

env glob(33);

int main(void)
// try
{
  cas1 case1;
  int i = static_cast<c2&>(case1).get();
  Pad scratch;
  case1.redirect(glob, scratch);
  return i + static_cast<c2&>(case1).get();
}
// catch (...)
// {}

env::env(int i) : i(i) {}
void c2::redirect(env& e, Pad& p)
{
  void* e1 = this;
  Pad*& p1 = *static_cast<Pad**>(e1);
  Pad* p2 = p1 - 1;
  p = *p2;
  p.offs = ptrdiff_t(&e) - ptrdiff_t(e1);
  p1 = &p + 1;
}

